package com.party.admin.biz.asynexport;

import com.alibaba.druid.support.json.JSONUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import com.party.admin.biz.file.ExcelExportService;
import com.party.admin.redisPubSub.publish.RedisMsgPublish;
import com.party.admin.redisPubSub.subscribe.SubScribeMessage;
import com.party.admin.utils.RealmUtils;
import com.party.admin.utils.excel.ExportExcel;
import com.party.common.constant.Constant;
import com.party.common.redis.StringJedis;
import com.party.common.utils.BigDecimalUtils;
import com.party.common.utils.DateUtils;
import com.party.core.model.YesNoStatus;
import com.party.core.model.crowdfund.CrowdfundEndFollowAdminOutput;
import com.party.core.model.crowdfund.CrowdfundEventWithMemberPartner;
import com.party.core.service.crowdfund.ICrowfundFollowUpService;
import com.party.core.service.order.IOrderFormService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @ClassName EventAsynExportService
 * @Description TODO
 * @Author yifeng
 * @Date 2019/10/31 9:55
 **/
@Service
public class EventAsynExportService {
    @Autowired
    private RedisMsgPublish redisMsgPublish;
    @Autowired
    private ICrowfundFollowUpService crowfundFollowUpService;
    @Autowired
    private IOrderFormService orderFormService;
    @Autowired
    private StringJedis stringJedis;
    @Autowired
    private ExcelExportService excelExportService;

    private Logger logger = LoggerFactory.getLogger(getClass());

    /**
     * 众筹结束跟进导出
     *
     * @param crowdfundEvent 主题参数
     * @param params         查询参数
     * @param sessionId      用户id
     * @author yifeng
     * @date 10:08 2019/10/31
     **/
    public void endExport(CrowdfundEventWithMemberPartner crowdfundEvent, Map<String, Object> params, String sessionId) {
        try {
            crowdfundEvent.setIsMultiple(YesNoStatus.NO.getCode());
            List<Map<String, Object>> crowdfundEventList = crowfundFollowUpService.endList(crowdfundEvent, params, null);

            List<CrowdfundEndFollowAdminOutput> cefoList = new ArrayList<>();

            Map<String, Map<String, Object>> mapList = Maps.newHashMap();

            ExecutorService threadPool = Executors.newFixedThreadPool(30);

            for (Map<String, Object> stringObjectMap : crowdfundEventList) {
                CrowdfundEndFollowAdminOutput crowdfundEndFollowAdminOutput = JSON.parseObject(JSON.toJSONString(stringObjectMap), CrowdfundEndFollowAdminOutput.class);
                threadPool.execute(() -> {
                    Map<String, Object> map = Maps.newHashMap();
                    String eventId = stringObjectMap.get("eventId").toString();

                    //剩余金额
                    Double payMoney = orderFormService.findPaymentByEventId(eventId);
                    map.put("remainMoney", BigDecimalUtils.round(payMoney, 2));

                    Integer followState = (Integer) stringObjectMap.get("followState");
                    String followStateName = "";
                    if (0 == followState) {
                        followStateName = "待处理";
                    } else if (1 == followState) {
                        followStateName = "跟进中";
                    } else if (2 == followState) {
                        followStateName = "处理完成";
                    }
                    map.put("followStateName", followStateName);

                    mapList.put(eventId, map);
                });

                cefoList.add(crowdfundEndFollowAdminOutput);
            }

            threadPool.shutdown();

            while (true) {
                if (threadPool.isTerminated()) {
                    logger.info("所有的子线程都结束了！");
                    break;
                }
            }


            cefoList.forEach(output -> {
                Map<String, Object> stringObjectMap = mapList.get(output.getEventId());
                if (null != stringObjectMap) {
                    Object remainMoney = stringObjectMap.get("remainMoney");
                    if (null != remainMoney) {
                        output.setRemainMoney((Double) remainMoney);
                    }
                    Object followStateName = stringObjectMap.get("followStateName");
                    if (null != followStateName) {
                        output.setFollowState((String) followStateName);
                    }
                }
            });

            String realPath = getBaseDir() + Constant.BATCH + Constant.EXCEL_URL + "eventEndFollow/";
            exportExcel("众筹结束跟进记录.xlsx", CrowdfundEndFollowAdminOutput.class, cefoList, realPath, "eventEndFollow", true);

            Map<String, String> json = Maps.newHashMap();
            json.put("memberId", RealmUtils.getCurrentUser().getId());
            json.put("sessionId", sessionId);
            json.put("message", "众筹结束跟进导出成功了");
            String param = JSONUtils.toJSONString(json);
            redisMsgPublish.publish(SubScribeMessage.CROWDFUND_EXPORT_CHANNEL_NAME, param);
        } catch (Exception e) {
            logger.error("导出异常", e);
            Map<String, String> json = Maps.newHashMap();
            json.put("memberId", RealmUtils.getCurrentUser().getId());
            json.put("sessionId", sessionId);
            json.put("message", "众筹结束跟进导出异常了");
            String param = JSONUtils.toJSONString(json);
            redisMsgPublish.publish(SubScribeMessage.CROWDFUND_EXPORT_CHANNEL_NAME, param);
        }
    }

    public void exportExcel(String title, Class<?> clazz, List<?> list, String realPath, String fileName, boolean isEnd) throws Exception {
        try {
            //导出
            ExportExcel exportExcel = new ExportExcel(title, clazz).setDataList(list);
            callBack(exportExcel, fileName, isEnd);
        } catch (Exception e) {
            logger.error("异步导出异常——" + title + ";" + realPath, e);
            throw e;
        }
    }

    public void callBack(ExportExcel exportExcel, String fileName1, boolean isEnd) {
        if (isEnd) {
            String fileName = fileName1 + ".xlsx";
            try {
                String allPath = excelExportService.getExcelPath(fileName, "project", exportExcel);
                logger.info("上传成功路径：{}", allPath);
                Map<String, Object> map = Maps.newHashMap();
                map.put("sourceUrl", allPath);
                map.put("uploadTime", DateUtils.formatDate(new Date(), DateUtils.DATETIME_PATTERN));

                //设置24小时过期
                stringJedis.setValue(Constant.PRE_ZIP_URL + fileName1, JSONObject.toJSONString(map));
            } catch (Exception e) {
                logger.error("众筹结束跟进上传文件异常", e);
            }
        }
    }

    public String getBaseDir() {
        return System.getProperty("user.dir").replaceAll("\\\\", "/");
    }
}
